package ntd.util.modular.data.util.handle.tool;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.BiMap;
import cn.hutool.core.map.TableMap;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.c.Constant;
import com.modular.iot.tool.ToolIotCmd;
import lj.netty.tool.LJTNetty;
import ntd.protocol.bo.Ntd212BO;
import ntd.util.UtilRun;
import ntd.util.frame.action.iot.bo.SmartEmissionAgreementBo;
import ntd.util.frame.action.iot.cache.SmartEmissionAgreementCache;
import ntd.util.modular.data.util.handle.constant.Constant212;
import ntd.util.str.bo.CutMsg;

import java.util.*;

/**
 * 212 协议辅助功能模块
 */
public class Tool212 {

    private static LJMapSet<String> mnNewMap = new LJMapSet<>();

    public static final List<String> DATA_CNS = ListUtil.of(
            Constant212.CN_2061,
            Constant212.CN_2051,
            Constant212.CN_2031,
            Constant212.CN_2011
    );

    /**
     * 获取切割函数对象
     * @return
     */
    public static CutMsg getCutMsg() {
        return new CutMsg().setStartTag("##").setEndTag("\r\n");
    }

    /**
     * 绑定外部编号
     * @param mn
     * @param channelId
     */
    public static void bindMn(String mn, String channelId) {
        if (StrUtil.isBlank(mn) || StrUtil.isBlank(channelId)) {
            return;
        }
        mnNewMap.put(mn, channelId);
    }

    /**
     * 根据通道编号查找外部编号
     * @param channelId
     * @return
     */
    public static String getMnByChannelId(String channelId) {
        return mnNewMap.getOneKeyByVal(channelId);
    }

    /**
     * 判断在线
     * @param mn
     * @return
     */
    public static boolean isOnLine(String mn) {
        boolean is_online = false;
        List<String> offKeys = new ArrayList<>();
        for (String key : mnNewMap.get(mn)) {
            boolean onLine = ObjectUtil.isNotNull(LJTNetty.getChannel(key));
            if (onLine) {
                is_online = true;
            } else {
                offKeys.add(key);
            }
        }
        for (String offKey : offKeys) {
            mnNewMap.del(mn, offKey);
        }
        return is_online;
    }

    public static boolean sendMsg(String mn, String msg) {
        if (StrUtil.isBlank(msg) || StrUtil.isBlank(mn)) {
            return false;
        }
        boolean is_success = false;
        if (isOnLine(mn)) {
            for (String key : mnNewMap.get(mn)) {
                StaticLog.info("212 指令发送 - [{}]", msg);
                is_success = LJTNetty.push(key, msg.getBytes()) || is_success;
            }
        }
        return is_success;
    }

    /**
     * 包装 212 指令对象 - 智能排污
     * @param mn
     * @param smartEmissionAgreementBo
     * @return
     */
    public static Ntd212BO build212Bo(String mn, SmartEmissionAgreementBo smartEmissionAgreementBo) {
        return build212Bo(mn, smartEmissionAgreementBo.toHexCmdStr());
    }

    /**
     * 包装 212 指令对象 - 智能排污
     * @param mn
     * @return
     */
    public static Ntd212BO build212Bo(String mn, String cmd) {
        Ntd212BO ntd212BO = build212Bo(mn);
        ntd212BO.setST("32");
        ntd212BO.setCN(String.valueOf(Constant212.CN_9801));
        if (StrUtil.isBlank(cmd)) {
            ntd212BO.setCP("&&&&");
        } else {
            ntd212BO.setCP(StrUtil.format("&&ExeRtn={}&&", StrUtil.padPre(cmd, 2, "0")));
        }
        return ntd212BO;
    }

    /**
     * 构建基础212对象
     * @param mn
     * @return
     */
    public static Ntd212BO build212Bo(String mn) {
        Ntd212BO ntd212BO = new Ntd212BO();
        ntd212BO.setQN(DateUtil.format(DateUtil.date(), Constant.DATE_FORMAT_WLW_FIVE));
        ntd212BO.setPW(Constant212.PASS);
        ntd212BO.setMN(mn);
        ntd212BO.setFlag("5");
        return ntd212BO;
    }

    public static void pushSt32Emergency(String mn, String des) {
        SmartEmissionAgreementBo smartEmissionAgreementBo = SmartEmissionAgreementCache.get(mn);

        Opt.ofNullable(smartEmissionAgreementBo).ifPresent(item -> {
            // 自动运行配置开启，才运行自动指令
            if (item.isAutoRun()) {
                UtilRun.jitterRun("device-power-off-exe", () -> {
                    // 如果排污阀打开或者应急阀关闭执行逻辑 - 验证原始状态，如果已经变动则不执行
                    if (smartEmissionAgreementBo.isValve() || !smartEmissionAgreementBo.isValve2()) {
                        // 关闭排污阀
                        smartEmissionAgreementBo.setValve(false);
                        // 打开应急阀
                        smartEmissionAgreementBo.setValve2(true);
                        // 推送应急处理
                        ToolIotCmd.pushCmd(mn,Tool212.build212Bo(mn, smartEmissionAgreementBo).to212Str(), ToolIotCmd.TYPE_212, des + "-应急指令");
                    }
                }, 1000 * 60 * 2);
            }
        });
    }

    /**
     * 生成回复消息
     * QN=20160801090000001;ST=91;CN=9014;PW=123456;MN=010000A8900016F000169DC0;Flag=4;CP=&&&&
     * @param ntd212BO
     * @return
     */
    public static String generatorResMsg(Ntd212BO ntd212BO) {
        Ntd212BO ntd212BORes = new Ntd212BO();
        ntd212BORes.setQN(ntd212BO.getQN());
        ntd212BORes.setST(ntd212BO.getST());
        ntd212BORes.setCN("9014");
        ntd212BORes.setPW(ntd212BO.getPW());
        ntd212BORes.setMN(ntd212BO.getMN());
        ntd212BORes.setFlag("4");
        ntd212BORes.setCP("&&&&");
        return ntd212BORes.to212Str();
    }

    public static void main(String[] args) {
        byte[] bytes = HexUtil.decodeHex("0d");
        StaticLog.info("hex - {}", JSONUtil.toJsonStr(bytes));
    }

}
